package com.yhy.wxzn.wcs.device.plc.xj;

import com.alibaba.fastjson.JSON;
import com.yhy.wxzn.common.enums.WcsDeviceTypeEnums;
import com.yhy.wxzn.common.enums.WcsPlcPropertyTypeEnums;
import com.yhy.wxzn.common.utils.ListHelper;
import com.yhy.wxzn.common.utils.SpringUtil;
import com.yhy.wxzn.wcs.device.rgv.bean.Coord;
import com.yhy.wxzn.wcs.device.rgv.bean.Lifter;
import com.yhy.wxzn.wcs.device.rgv.bean.Node;
import com.yhy.wxzn.wcs.entity.WcsDeviceInfo;
import com.yhy.wxzn.wcs.device.plc.bean.*;
import com.yhy.wxzn.wcs.entity.WcsPlcConfig;
import com.yhy.wxzn.wcs.entity.WcsPlcProperty;
import com.yhy.wxzn.wcs.service.IWcsDeviceInfoService;
import com.yhy.wxzn.wcs.service.impl.WcsDeviceInfoServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.yhy.wxzn.wcs.SystemInit.*;


/**
 * @Auther: 97354
 * @Date: 2023/11/6 16:07
 * @Description: PlcServer
 * @Version 1.0.0
 */
@Slf4j
public class XjPlcServer {

    private IWcsDeviceInfoService deviceInfoService = SpringUtil.getBean(IWcsDeviceInfoService.class);
    //plcName->plc通讯类
    public static Map<String, XjPlcDriver> plcDriverMap = new ConcurrentHashMap<>();
    //deviceId->提升机任务线程
    public static Map<Integer, XjHoistProtocol> hoistProtocolMap = new ConcurrentHashMap<>();
    //deviceId->输送线扫码称重任务线程
    public static Map<Integer, XjPlcProtocol> plcProtocolMap = new ConcurrentHashMap<>();



    public void initProtocol(WcsPlcConfig plc, Map<Integer, List<WcsPlcProperty>> propertyMap) {
        //初始化业务类
        String plcIp = plc.getIp();//IP地址
        int port = plc.getPort();//端口
        String plcName = plc.getPlcName();//PLC名称


        XjPlcDriver xjPlcDriver = new XjPlcDriver(plcIp,port,plcName);
        plcDriverMap.put(plcName,xjPlcDriver);


        propertyMap.entrySet().stream().forEach(p -> {
            String deviceId = String.valueOf(p.getKey());

            //根据设备加载对应的点位到内存
            List<WcsPlcProperty> plcProperties = p.getValue();
            //加载设备心跳点位到内存
            //createHeartBeatMap(deviceId,xjPlcDriver,plcProperties);
            //加载出入库口点位到内存
            createPortMap(deviceId,xjPlcDriver,plcProperties);
            //加载输送线点位到内存
            createTransLineMap(deviceId,xjPlcDriver,plcProperties);
            //加载提升机点位到内存
            createHoistMap(deviceId,xjPlcDriver,plcProperties);
            //加载四向车点位到内存
            createFourCarMap(deviceId,xjPlcDriver,plcProperties);
        });

        xjPlcDriver.start();


        propertyMap.entrySet().stream().forEach(p -> {

            WcsDeviceInfo deviceInfo = deviceInfoService.getById(p.getKey());
            //输送线业务处理线程
            if(deviceInfo.getDeviceType().intValue() == WcsDeviceTypeEnums.TSL.getValue().intValue()){
                XjPlcProtocol xjPlcProtocol = new XjPlcProtocol(plcName);
                xjPlcProtocol.xjPlcDriver = XjPlcServer.plcDriverMap.get(plcName);
                plcProtocolMap.put(deviceInfo.getId(), xjPlcProtocol);
                xjPlcProtocol.start();
            }
            //提升机业务处理线程-需加载设备信息
            if(deviceInfo.getDeviceType().intValue() == WcsDeviceTypeEnums.ELV.getValue().intValue()){
                XjHoistProtocol xjHoistProtocol = new XjHoistProtocol(plcName,deviceInfo,xjPlcDriver);
                hoistProtocolMap.put(deviceInfo.getId(), xjHoistProtocol);
                xjHoistProtocol.start();
            }
        });
    }

    /**
     * 四向车设备以及点位信息
     * */
    private void createFourCarMap(String deviceId, XjPlcDriver plcDriver, List<WcsPlcProperty> plcProperties) {
        int typeDevice = WcsPlcPropertyTypeEnums.FOURCAR.getValue();
        List<WcsPlcProperty> listDevice = ListHelper.where(plcProperties, m -> m.getType() == typeDevice);
        listDevice.forEach(m -> {
            WcsDeviceInfo deviceInfo = deviceInfoService.getById(deviceId);
            if(!deviceInfo.getStatus() ) return;

            FourCarPlc fourCarPlc = new FourCarPlc();
            BeanUtils.copyProperties(m, fourCarPlc);
            fourCarPlc.setDeviceId(deviceId);
            fourCarPlc.setCarNo(deviceId);
            plcDriver.getDriverData().getFourCarPlcMap().put(deviceId, fourCarPlc);
            plcRgvIds.add(Integer.valueOf(deviceId));
            rgvPlcMap.put(Integer.valueOf(deviceId),fourCarPlc);
            rgvDriverMap.put(Integer.valueOf(deviceId),plcDriver);



            nameToBasePlc.put(deviceInfo.getDeviceName(),fourCarPlc);
        });
        /**
         * 一些特殊点位
         * */
        int typeCoord = WcsPlcPropertyTypeEnums.FOURCARCOORD.getValue();
        List<WcsPlcProperty> listCoord = ListHelper.where(plcProperties, m -> m.getType() == typeCoord);
        listCoord.forEach(m -> {
            BasePlc coordPlc = new BasePlc();
            BeanUtils.copyProperties(m, coordPlc);
            coordPlc.setDeviceId(deviceId);
            plcDriver.getDriverData().getCoordPlcMap().put(m.getCoord(),coordPlc);
        });
    }

    /**
     * 提升机设备以及点位
     * */
    private void createHoistMap(String deviceId, XjPlcDriver plcDriver, List<WcsPlcProperty> plcProperties) {
        int typeDevice = WcsPlcPropertyTypeEnums.HOIST.getValue();
        List<WcsPlcProperty> list = ListHelper.where(plcProperties, m -> m.getType() == typeDevice);
        list.forEach(m -> {
            WcsDeviceInfo deviceInfo = deviceInfoService.getById(deviceId);
            if(!deviceInfo.getStatus() ) return;
            XJPHoistPlc hoistPlc = new XJPHoistPlc();
            BeanUtils.copyProperties(m, hoistPlc);
            hoistPlc.setDeviceId(deviceId);
            plcDriver.getDriverData().getXJPhoistPlcMap().put(deviceId, hoistPlc);
            liferPlcMap.put(Integer.valueOf(deviceId),hoistPlc);
            liferDriverMap.put(Integer.valueOf(deviceId),plcDriver);



            Lifter location = Lifter.parseLifter(deviceInfo.getLocation());

            liferToDeviceIdMap.put(location,Integer.valueOf(deviceId));

//            liferToHoistPlcMap.put(location,hoistPlc);

            nameToBasePlc.put(deviceInfo.getDeviceName(),hoistPlc);
        });
        /**
         * 一些特殊点位
         * */
        int typeCoord = WcsPlcPropertyTypeEnums.HOISTCOORD.getValue();
        List<WcsPlcProperty> listCoord = ListHelper.where(plcProperties, m -> m.getType() == typeCoord);
        listCoord.forEach(m -> {
            BasePlc coordPlc = new BasePlc();
            BeanUtils.copyProperties(m, coordPlc);
            coordPlc.setDeviceId(deviceId);
            plcDriver.getDriverData().getCoordPlcMap().put(m.getCoord(),coordPlc);
        });
    }

    private void createTransLineMap(String deviceId, XjPlcDriver plcDriver, List<WcsPlcProperty> plcProperties) {
        int type = WcsPlcPropertyTypeEnums.TRANSLINE.getValue();
        List<WcsPlcProperty> list = ListHelper.where(plcProperties, m -> m.getType() == type);
        list.forEach(m -> {
            WcsDeviceInfo deviceInfo = deviceInfoService.getById(deviceId);
            if(!deviceInfo.getStatus() ) return;
            XJPTransmissionPlc transmissionPlc = new XJPTransmissionPlc();
            BeanUtils.copyProperties(m, transmissionPlc);
            transmissionPlc.setDeviceId(deviceId);
            plcDriver.getDriverData().getXJPtransLinePlcMap().put(deviceId, transmissionPlc);
            transmissionDriverMap.put(Integer.valueOf(deviceId), plcDriver);

//            String location = deviceInfo.getLocation();
//            Coord coord = Node.parseCoord(location);
//            coordToTransmissionPlcMap.put(coord,transmissionPlc);

            nameToBasePlc.put(deviceInfo.getDeviceName(),transmissionPlc);
        });
    }

    private void createPortMap(String deviceId, XjPlcDriver plcDriver, List<WcsPlcProperty> plcProperties) {
        int type = WcsPlcPropertyTypeEnums.PORT.getValue();
        List<WcsPlcProperty> list = ListHelper.where(plcProperties, m -> m.getType() == type);
        list.forEach(m -> {
            PortPlc portPlc = new PortPlc();
            BeanUtils.copyProperties(m, portPlc);
            portPlc.setDeviceId(deviceId);
            plcDriver.getDriverData().getPortPlcMap().put(deviceId, portPlc);
            WcsDeviceInfo deviceInfo = deviceInfoService.getById(deviceId);
            nameToBasePlc.put(deviceInfo.getDeviceName(),portPlc);
        });
    }

    /**
     *一个设备1个心跳点位
     * */
    private void createHeartBeatMap(String deviceId, XjPlcDriver plcDriver, List<WcsPlcProperty> plcProperties) {
        int type = WcsPlcPropertyTypeEnums.HEARTBEAT.getValue();
        List<WcsPlcProperty> list = ListHelper.where(plcProperties, m -> m.getType() == type);
        list.forEach(m -> {
            HeartBeatPlc heartBeatPlc = new HeartBeatPlc();
            BeanUtils.copyProperties(m, heartBeatPlc);
            heartBeatPlc.setDeviceId(deviceId);
            plcDriver.getDriverData().getHeartBeatPlcMap().put(deviceId,heartBeatPlc);
        });
    }
}
